﻿using System;
using System.Configuration;
using CookComputing.XmlRpc;

namespace InfusionSoftDotNet
{
    public class isdnAPI
    {
        public static string _AppName = ConfigurationManager.AppSettings["iSdk-AppName"];
        public static string _AppType = ConfigurationManager.AppSettings["iSdk-AppType"];
        public static string _ApiKey = ConfigurationManager.AppSettings["iSdk-ApiKey"];
        public static string _ApiURL = String.Format("https://{0}.{1}.com/api/xmlrpc",
            _AppName,
            (_AppType == "m" ? "mortgageprocrm" : "infusionsoft"));

        /// <summary>
        /// Hold onto the last exception generated by any method call.
        /// </summary>
        public static Exception  _LastException = null;

        #region AffiliateService
        public static XmlRpcStruct[] affClawbacks(int affiliateId, DateTime filterStartDate, DateTime filterEndDate)
        {
            return affClawbacks(affiliateId, isdnExtensions.infuDate(filterStartDate), isdnExtensions.infuDate(filterEndDate));
        }
        public static XmlRpcStruct[] affClawbacks(int affiliateId, string filterStartDate, string filterEndDate)
        {
            XmlRpcStruct[] ret_value;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.asAffClawbacks(_ApiKey, affiliateId, filterStartDate, filterEndDate);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = new XmlRpcStruct[1] { fail };
            }
            return ret_value;
        }
        public static XmlRpcStruct[] affCommissions(int affiliateId, DateTime filterStartDate, DateTime filterEndDate)
        {
            return affCommissions(affiliateId, isdnExtensions.infuDate(filterStartDate), isdnExtensions.infuDate(filterEndDate));
        }
        public static XmlRpcStruct[] affCommissions(int affiliateId, string filterStartDate, string filterEndDate)
        {
            XmlRpcStruct[] ret_value;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.asAffCommissions(_ApiKey, affiliateId, filterStartDate, filterEndDate);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = new XmlRpcStruct[1] { fail };
            }
            return ret_value;
        }
        public static XmlRpcStruct[] affPayouts(int affiliateId, DateTime filterStartDate, DateTime filterEndDate)
        {
            return affPayouts(affiliateId, isdnExtensions.infuDate(filterStartDate), isdnExtensions.infuDate(filterEndDate));
        }
        public static XmlRpcStruct[] affPayouts(int affiliateId, string filterStartDate, string filterEndDate)
        {
            XmlRpcStruct[] ret_value;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.asAffPayouts(_ApiKey, affiliateId, filterStartDate, filterEndDate);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = new XmlRpcStruct[1] { fail };
            }
            return ret_value;
        }
        public static XmlRpcStruct[] affRunningTotals(int[] affiliateIds)
        {
            XmlRpcStruct[] ret_value;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.asAffRunningTotals(_ApiKey, affiliateIds);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = new XmlRpcStruct[1] { fail };
            }
            return ret_value;
        }
        public static XmlRpcStruct[] affSummary(int affiliateId, DateTime filterStartDate, DateTime filterEndDate)
        {
            return affSummary(affiliateId, isdnExtensions.infuDate(filterStartDate), isdnExtensions.infuDate(filterEndDate));
        }
        public static XmlRpcStruct[] affSummary(int affiliateId, string filterStartDate, string filterEndDate)
        {
            XmlRpcStruct[] ret_value;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.asAffSummary(_ApiKey, affiliateId, filterStartDate, filterEndDate);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = new XmlRpcStruct[1] { fail };
            }
            return ret_value;
        }
        #endregion

        #region ContactService
        #region Core methods
        public static int add(XmlRpcStruct cMap)
        {
            int ret_value = 0;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.addCon(_ApiKey, cMap);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }
            return ret_value;
        }
        public static int addWithDupCheck(XmlRpcStruct cMap, string dupCheckType)
        {
            int ret_value = 0;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.addWithDupCheck(_ApiKey, cMap, dupCheckType);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }
            return ret_value;
        }

        public static XmlRpcStruct[] findByEmail(string email, string[] returnFields)
        {
            XmlRpcStruct[] retArray;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                retArray = api.findByEmail(_ApiKey, email, returnFields);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                XmlRpcStruct[] retFail = new XmlRpcStruct[1] { fail };
                retArray = retFail;
            }
            return retArray;
        }

        public static XmlRpcStruct load(int Id, string[] selectedFields)
        {
            XmlRpcStruct retContact;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                retContact = api.load(_ApiKey, Id, selectedFields);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                retContact = fail;
            }
            return retContact;
        }

        public static int update(int contactId, XmlRpcStruct cMap)
        {
            int ret_value = 0;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.updateCon(_ApiKey, contactId, cMap);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }
            return ret_value;
        }

        #endregion

        #region Follow up sequence methods
        public static bool addToCampaign(int contactId, int campaignId)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.addToCampaign(_ApiKey, contactId, campaignId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        public static int getNextCampaignStep(int contactId, int campaignId)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.getNextCampaignStep(_ApiKey, contactId, campaignId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }
            return ret_value;
        }

        public static bool pauseCampaign(int contactId, int campaignId)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.pauseCampaign(_ApiKey, contactId, campaignId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        public static bool removeFromCampaign(int contactId, int campaignId)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.removeFromCampaign(_ApiKey, contactId, campaignId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        public static bool resumeCampaign(int contactId, int campaignId)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.resumeCampaign(_ApiKey, contactId, campaignId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        public static bool resumeCampaignForContact(int contactId, int campaignId)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.resumeCampaignForContact(_ApiKey, contactId, campaignId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        public static int rescheduleCampaignStep(Array contactIds, int campaignStepId)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.rescheduleCampaignStep(_ApiKey, contactIds, campaignStepId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }
            return ret_value;
        }
        #endregion

        #region Tag methods
        public static bool addToGroup(int contactId, int groupId)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.addToGroup(_ApiKey, contactId, groupId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        public static bool removeFromGroup(int contactId, int groupId)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.removeFromGroup(_ApiKey, contactId, groupId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }
        #endregion

        #region Action methods
        // TODO - MJG - gotta figure out the equivalent of *struct params in .Net
        //public XmlRpcStruct runActionSequence(int contactId, int actionSequenceID, *struct params)
        #endregion
        #endregion

        #region DataService
        public static int dsAdd(string table, XmlRpcStruct values)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.dsAdd(_ApiKey, table, values);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }
            return ret_value;
        }

        public static XmlRpcStruct dsLoad(string table, int Id, string[] fields)
        {
            XmlRpcStruct retStruct;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                retStruct = api.dsLoad(_ApiKey, table, Id, fields);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                retStruct = fail;
            }
            return retStruct;
        }

        public static int dsUpdate(string table, int Id, XmlRpcStruct fields)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.dsUpdate(_ApiKey, table, Id, fields);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }
            return ret_value;
        }

        public static bool dsDelete(string table, int Id)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.dsDelete(_ApiKey, table, Id);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        public static XmlRpcStruct[] dsFindByField(string table, int limit, int page, string fieldName, string fieldValue, string[] selectedFields)
        {
            XmlRpcStruct[] retStructArray;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                retStructArray = api.dsFindByField(_ApiKey, table, limit, page, fieldName, fieldValue, selectedFields);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                XmlRpcStruct[] retFail = new XmlRpcStruct[1] { fail };
                retStructArray = retFail;
            }
            return retStructArray;
        }

        public static XmlRpcStruct[] dsQuery(string table, int limit, int page, XmlRpcStruct queryData, string[] selectedFields)
        {
            XmlRpcStruct[] retStructArray;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                retStructArray = api.dsQuery(_ApiKey, table, limit, page, queryData, selectedFields);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                XmlRpcStruct[] retFail = new XmlRpcStruct[1] { fail };
                retStructArray = retFail;
            }
            return retStructArray;
        }

        public static int dsAddCustomField(string context, string displayName, string dataType, int groupId)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.dsAddCustomField(_ApiKey, context, displayName, dataType, groupId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }
            return ret_value;
        }

        public static int dsAuthenticateUser(string username, string passwordHash)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.dsAuthenticateUser(_ApiKey, username, passwordHash);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }
            return ret_value;
        }

        public static string dsGetAppSetting(string module, string setting)
        {
            string ret_value = string.Empty;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.dsGetAppSetting(_ApiKey, module, setting);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = string.Empty;
            }
            return ret_value;
        }

        public static string dsGetTemporaryKey(string username, string passwordHash)
        {
            string ret_value = string.Empty;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.dsGetTemporaryKey(_ApiKey, username, passwordHash);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = string.Empty;
            }
            return ret_value;
        }

        public static bool dsUpdateCustomField(int customFieldId, XmlRpcStruct values)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.dsUpdateCustomField(_ApiKey, customFieldId, values);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        #endregion

        #region DiscountService
        public static int addFreeTrial(string description, int freeTrialDays, int hidePrice, int subscriptionPlanId)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disAddFreeTrial(_ApiKey, description, freeTrialDays, hidePrice, subscriptionPlanId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }
        public static XmlRpcStruct getFreeTrial(int trialId)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disGetFreeTrial(_ApiKey, trialId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }
            return ret_value;
        }
        public static int addOrderTotalDiscount(string name, string description, int applyDiscountToCommission, int percentOrAmt, int amt, int payType)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disAddOrderTotalDiscount(_ApiKey, name, description, applyDiscountToCommission, percentOrAmt, amt, payType);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }
        public static XmlRpcStruct getOrderTotalDiscount(int id)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disGetOrderTotalDiscount(_ApiKey, id);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }
            return ret_value;
        }
        public static int addCategoryDiscount(string name, string description, int applyDiscountToCommission, int amt)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disAddCategoryDiscount(_ApiKey, name, description, applyDiscountToCommission, amt);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }
        public static XmlRpcStruct getCategoryDiscount(int id)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disGetCategoryDiscount(_ApiKey, id);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }
            return ret_value;
        }
        public static int addCategoryAssignmentToCategoryDiscount(int productId)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disAddCategoryAssignmentToCategoryDiscount(_ApiKey, productId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }
        public static XmlRpcStruct getCategoryAssignmentsForCategoryDiscount(int id)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disGetCategoryAssignmentsForCategoryDiscount(_ApiKey, id);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }
            return ret_value;
        }
        public static int addProductTotalDiscount(string name, string description, int applyDiscountToCommission, int productId, int percentOrAmount, int amt)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disAddProductTotalDiscount(_ApiKey, name, description, applyDiscountToCommission, productId, percentOrAmount, amt);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }
        public static XmlRpcStruct getProductTotalDiscount(int id)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disGetProductTotalDiscount(_ApiKey, id);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }
            return ret_value;
        }
        public static int addShippingTotalDiscount(string name, string description, int applyDiscountToCommission, int percentOrAmount, int amt)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disAddShippingTotalDiscount(_ApiKey, name, description, applyDiscountToCommission, percentOrAmount, amt);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }
        public static XmlRpcStruct getShippingTotalDiscountl(int id)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.disGetShippingTotalDiscount(_ApiKey, id);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }
            return ret_value;
        }

        #endregion

        #region EmailService
        /// <summary>
        /// Creates a new email template that can be used for future emails.
        /// mergeContext choices:Contact, ServiceCall, Opportunity and CreditCard
        /// contentType choices: html, text or multipart
        /// </summary>
        /// <param name="pieceTitle"></param>
        /// <param name="categories"></param>
        /// <param name="fromAddress"></param>
        /// <param name="toAddress"></param>
        /// <param name="ccAddress"></param>
        /// <param name="bccAddress"></param>
        /// <param name="subject"></param>
        /// <param name="textBody"></param>
        /// <param name="htmlBody"></param>
        /// <param name="contentType"></param>
        /// <param name="mergeContext"></param>
        /// <returns>Returns templateId of the created email template</returns>
        public static int addEmailTemplate(string pieceTitle, string categories, string fromAddress, string toAddress, string ccAddress, string bccAddress, string subject, string textBody, string htmlBody, string contentType, string mergeContext)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esAddEmailTemplate(_ApiKey, pieceTitle, categories, fromAddress, toAddress, ccAddress, bccAddress, subject, textBody, htmlBody, contentType, mergeContext);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }

        public static bool attachEmail(int ContactId, string fromName, string fromAddress, string toAddress, string ccAddresses, string bccAddresses, string contentType, string subject, string htmlBody, string textBody, string header, DateTime receivedDate, DateTime sentDate, int emailSentType)
        {
            return attachEmail(ContactId, fromName, fromAddress, toAddress, ccAddresses, bccAddresses, contentType, subject, htmlBody, textBody, header, isdnExtensions.infuDate(receivedDate), isdnExtensions.infuDate(sentDate), emailSentType);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ContactId"></param>
        /// <param name="fromName"></param>
        /// <param name="fromAddress"></param>
        /// <param name="toAddress"></param>
        /// <param name="ccAddresses"></param>
        /// <param name="bccAddresses"></param>
        /// <param name="contentType"></param>
        /// <param name="subject"></param>
        /// <param name="htmlBody"></param>
        /// <param name="textBody"></param>
        /// <param name="header"></param>
        /// <param name="receivedDate"></param>
        /// <param name="sentDate"></param>
        /// <param name="emailSentType"></param>
        /// <returns></returns>
        public static bool attachEmail(int ContactId, string fromName, string fromAddress, string toAddress, string ccAddresses, string bccAddresses, string contentType, string subject, string htmlBody, string textBody, string header, string receivedDate, string sentDate, int emailSentType)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esAttachEmail(_ApiKey, ContactId, fromName, fromAddress, toAddress, ccAddresses, bccAddresses, contentType, subject, htmlBody, textBody, header, receivedDate, sentDate, emailSentType);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        /// <summary>
        /// createEmailTemplate has been deprecated in favor of using addEmailTemplate instead
        /// </summary>
        /// <param name="templateTemplate"></param>
        /// <param name="userId"></param>
        /// <param name="fromAddress"></param>
        /// <param name="toAddress"></param>
        /// <param name="ccAddresses"></param>
        /// <param name="bccAddresses"></param>
        /// <param name="contentType"></param>
        /// <param name="subject"></param>
        /// <param name="htmlBody"></param>
        /// <param name="textBody"></param>
        /// <returns></returns>
        //public static Int32 createEmailTemplate(String templateTemplate, Int32 userId, String fromAddress, String toAddress, String ccAddresses, String bccAddresses, String contentType, String subject, String htmlBody, String textBody)
        //{
        //    Int32 ret_value = 0;
        //    _LastException = null;
        //    try
        //    {
        //        InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
        //        api.Url = _ApiURL;
        //        ret_value = api.esCreateEmailTemplate(_ApiKey, templateTemplate, userId, fromAddress, toAddress, ccAddresses, bccAddresses, contentType, subject, htmlBody, textBody);
        //    }
        //    catch (Exception ex)
        //    {
        //        _LastException = ex;
        //        ret_value = -1;
        //    }
        //    return ret_value;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mergeContext"></param>
        /// <returns></returns>
        public static string[] getAvailableMergeFields(string mergeContext)
        {
            string[] ret_value = { "Error" };
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esGetAvailableMergeFields(_ApiKey, mergeContext);
                // valid mergeContext values are html, text or multipart
            }
            catch (Exception ex)
            {
                _LastException = ex;
            }
            return ret_value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="templateId"></param>
        /// <returns></returns>
        public static XmlRpcStruct getEmailTemplate(int templateId)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esGetEmailTemplate(_ApiKey, templateId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = new XmlRpcStruct();
            }
            return ret_value;
        }

        /// <summary>
        /// getOptStatus indicates the status of a given customer found by email address
        /// </summary>
        /// <param name="key"></param>
        /// <param name="email"></param>
        /// <returns>Returns 0 if the customer is not opted in, 1 if they are single opted in, 2 if they are double opted in, </returns>
        public static int getOptStatus(string email)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esGetOptStatus(_ApiKey, email);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }

        /// <summary>
        /// OptIn contact
        /// </summary>
        /// <param name="key"></param>
        /// <param name="email"></param>
        /// <param name="permissionReason"></param>
        /// <returns>true if OptIn was successful, false if not. Will return false if already opted in</returns>
        public static bool optIn(string email, string permissionReason)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esOptIn(_ApiKey, email, permissionReason);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        /// <summary>
        /// OptOut contact
        /// </summary>
        /// <param name="key"></param>
        /// <param name="email"></param>
        /// <param name="permissionReason"></param>
        /// <returns>true if OptOut was successful, false if not. Will return false if already opted out</returns>
        public static bool optOut(string email, string revokeReason)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esOptOut(_ApiKey, email, revokeReason);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="contactList"></param>
        /// <param name="fromAddress"></param>
        /// <param name="toADdress"></param>
        /// <param name="ccAddresses"></param>
        /// <param name="bccAddresses"></param>
        /// <param name="contentType"></param>
        /// <param name="htmlBody"></param>
        /// <param name="textBody"></param>
        /// <returns></returns>
        public static bool sendEmail(string[] contactList, string fromAddress, string toADdress, string ccAddresses, string bccAddresses, string contentType, string htmlBody, string textBody)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esSendEmail(_ApiKey, contactList, fromAddress, toADdress, ccAddresses, bccAddresses, contentType, htmlBody, textBody);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        /// <summary>
        /// sendEmail(string[] contactList, int templateId) has been deprecated and is maintained only. Use sendTemplate() instead...
        /// </summary>
        /// <param name="contactList">string array of contacts to send to</param>
        /// <param name="templateId">integer of the template ID to use</param>
        /// <returns>boolean indicating success</returns>
        public static bool sendEmail(string[] contactList, int templateId)
        {
            bool ret_value = false;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esSendTemplate(_ApiKey, contactList, templateId);
            }
            catch (Exception ex)
            {
                ret_value = false;
            }

            return ret_value;
        }
        /// <summary>
        /// sendTemplate() will send an email using a pre-built template
        /// </summary>
        /// <param name="contactList">string array of contacts to send to</param>
        /// <param name="templateId">integer of the template ID to use</param>
        /// <returns>boolean indicating success</returns>
        public static bool sendTemplate(string[] contactList, int templateId)
        {
            bool ret_value = false;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esSendTemplate(_ApiKey, contactList, templateId);
            }
            catch (Exception ex)
            {
                ret_value = false;
            }

            return ret_value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="templateId"></param>
        /// <param name="pieceTitle"></param>
        /// <param name="categories"></param>
        /// <param name="fromAddress"></param>
        /// <param name="toAddress"></param>
        /// <param name="ccAddress"></param>
        /// <param name="bccAddress"></param>
        /// <param name="subject"></param>
        /// <param name="textBody"></param>
        /// <param name="htmlBody"></param>
        /// <param name="contentType"></param>
        /// <param name="mergeContext"></param>
        /// <returns></returns>
        public static bool updateEmailTemplate(int templateId, string pieceTitle, string categories, string fromAddress, string toAddress, string ccAddress, string bccAddress, string subject, string textBody, string htmlBody, string contentType, string mergeContext)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.esUpdateEmailTemplate(_ApiKey, templateId, pieceTitle, categories, fromAddress, toAddress, ccAddress, bccAddress, subject, textBody, htmlBody, contentType, mergeContext);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }
        #endregion

        #region FileService
        public static string getFile(int FileId)
        {
            string ret_value = string.Empty;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.fsGetFile(_ApiKey, FileId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = string.Empty;
            }
            return ret_value;
        }
        public static string getDownloadUrl(int FileId)
        {
            string ret_value = string.Empty;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.fsGetDownloadUrl(_ApiKey, FileId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = string.Empty;
            }
            return ret_value;
        }
        public static int uploadFile(string FileName, string Base64EncodedData)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.fsUploadFile(_ApiKey, FileName, Base64EncodedData);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }
        public static int uploadFile(string FileName, string Base64EncodedData, int ContactId)
        {
            int ret_value = -1;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.fsUploadFile(_ApiKey, FileName, Base64EncodedData, ContactId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -2;
            }
            return ret_value;
        }
        public static bool replaceFile(int FileId, string Base64EncodedData)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.fsReplaceFile(_ApiKey, FileId, Base64EncodedData);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }
        public static bool renameFile(int FileId, string fileName)
        {
            bool ret_value = false;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.fsRenameFile(_ApiKey, FileId, fileName);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }
            return ret_value;
        }

        #endregion

        #region InvoiceService
        #region core methods
        /// <summary>
        /// createBlankOrder will create a blank order for the given contactId. This empty order is then set to begin adding items into which would be the next step in the ecommerce transaction 
        /// </summary>
        /// <param name="contactId"></param>
        /// <param name="description"></param>
        /// <param name="orderDate"></param>
        /// <param name="leadAffiliate"></param>
        /// <param name="saleAffiliate"></param>
        /// <returns>new order ID</returns>
        public static int createBlankOrder(int contactId, string description, DateTime orderDate, int leadAffiliate, int saleAffiliate)
        {
            return createBlankOrder(contactId, description, isdnExtensions.infuDate(orderDate), leadAffiliate, saleAffiliate);
        }
        public static int createBlankOrder(int contactId, string description, string orderDate, int leadAffiliate, int saleAffiliate)
        {
            int newOrderNumber = 0;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                newOrderNumber = api.isCreateBlankOrder(_ApiKey, contactId, description, orderDate, leadAffiliate, saleAffiliate);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                newOrderNumber = -1;
            }

            return newOrderNumber;
        }

        /// <summary>
        /// addOrderItem adds a product to an existing order/invoice.
        /// </summary>
        /// <param name="invoiceId"></param>
        /// <param name="productId"></param>
        /// <param name="type">one of [UNKNOWN = 0; SHIPPING = 1; TAX = 2; SERVICE = 3; PRODUCT = 4; UPSELL = 5; FINANCECHARGE = 6; SPECIAL = 7;]</param>
        /// <param name="Price"></param>
        /// <param name="quantity"></param>
        /// <param name="description">a short description of the title, typically you will want to use its name</param>
        /// <param name="notes">a long description of the title, typically you will want to use the product’s description field</param>
        /// <returns>true/false indicating success of the add attempt</returns>
        public static bool addOrderItem(int invoiceId, int productId, int type, double price, int quantity, string description, string notes)
        {
            bool success = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                success = api.isAddOrderItem(_ApiKey, invoiceId, productId, type, price, quantity, description, notes);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                success = false;
            }

            return success;
        }

        /// <summary>
        /// chargeInvoice Charges a customer’s credit card for the outstanding amount on an existing invoice. You’ll need to have a creditCardId to use, which can be found with locateExistingCard() if your customer has purchased from you before, or from the DataService class if you need to insert a new credit card
        /// </summary>
        /// <param name="invoiceId"></param>
        /// <param name="notes"></param>
        /// <param name="creditCardId"></param>
        /// <param name="merchantAccountId"></param>
        /// <param name="bypassCommissions"></param>
        /// <returns>(struct) a struct containing payment details. The struct will contain the following keys:
        ///            * Successful – true or fale on whether or not the card was charged. (If there was nothing to charge, this will be false)
        ///            * Code – The approval code: APPROVED, DECLINED, ERROR, SKIPPED (there was no balance to charge)
        ///            * RefNum – If charge was successful, this is the reference number passed back by the merchant account
        ///            * Message – Error message for the transaction, if any
        /// </returns>
        public static XmlRpcStruct chargeInvoice(int invoiceId, string notes, int creditCardId, int merchantAccountId, bool bypassCommissions)
        {
            XmlRpcStruct paymentDetails = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                paymentDetails = api.isChargeInvoice(_ApiKey, invoiceId, notes, creditCardId, merchantAccountId, bypassCommissions);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                //paymentDetails = ;
            }

            return paymentDetails;
        }

        // public static Boolean deleteInvoice() // deleted from API

        public static bool deleteSubscription(int Id)
        {
            bool success = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                success = api.isDeleteSubscription(_ApiKey, Id);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                success = false;
            }

            return success;
        }
        #endregion

        #region Subscription methods
        public static int addRecurringOrder(int contactId, bool allowDuplicate, int cProgramId, int qty, double price, bool allowTax, int merchantAccountId, int creditCardId, int affiliateId, int daysTillCharge)
        {
            int ret_value = 0;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isAddRecurringOrder(_ApiKey, contactId, allowDuplicate, cProgramId, qty, price, allowTax, merchantAccountId, creditCardId, affiliateId, daysTillCharge);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = 0;
            }

            return ret_value;
        }

        public static bool addRecurringCommissionOverride(int recurringOrderId, int affiliateId, double amount, int payoutType, string description)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isAddRecurringCommissionOverride(_ApiKey, recurringOrderId, affiliateId, amount, payoutType, description);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }

        public static int createInvoiceForRecurring(int recurringOrderId)
        {
            int ret_value = 0;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isCreateInvoiceForRecurring(_ApiKey, recurringOrderId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = 0;
            }

            return ret_value;
        }
        public static bool updateJobRecurringNextBillDate(int jobRecurringId, DateTime newNextBillDate)
        {
            return updateJobRecurringNextBillDate(jobRecurringId, isdnExtensions.infuDate(newNextBillDate));
        }
        public static bool updateJobRecurringNextBillDate(int jobRecurringId, string newNextBillDate)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isUpdateJobRecurringNextBillDate(_ApiKey, jobRecurringId, newNextBillDate);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }
        #endregion

        #region Payment methods
        public static bool addManualPayment(int invoiceId, double amt, DateTime paymentDate, string paymentType, string paymentDescription, bool bypassCommissions)
        {
            return addManualPayment(invoiceId, amt, isdnExtensions.infuDate(paymentDate), paymentType, paymentDescription, bypassCommissions);
        }
        public static bool addManualPayment(int invoiceId, double amt, string paymentDate, string paymentType, string paymentDescription, bool bypassCommissions)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isAddManualPayment(_ApiKey, invoiceId, amt, paymentDate, paymentType, paymentDescription, bypassCommissions);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }
        public static bool addPaymentPlan(int invoiceId, bool autoCharge, int creditCardId, int merchantAccountId, int daysBetweenRetry, int maxRetry, double initialPmtAmt, DateTime initialPmtDate, DateTime planStartDate, int numPmts, int dayBetweenPmts)
        {
            return addPaymentPlan(invoiceId, autoCharge, creditCardId, merchantAccountId, daysBetweenRetry, maxRetry, initialPmtAmt, isdnExtensions.infuDate(initialPmtDate), isdnExtensions.infuDate(planStartDate), numPmts, dayBetweenPmts);
        }
        public static bool addPaymentPlan(int invoiceId, bool autoCharge, int creditCardId, int merchantAccountId, int daysBetweenRetry, int maxRetry, double initialPmtAmt, string initialPmtDate, string planStartDate, int numPmts, int dayBetweenPmts)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isAddPaymentPlan(_ApiKey, invoiceId, autoCharge, creditCardId, merchantAccountId, daysBetweenRetry, maxRetry, initialPmtAmt, initialPmtDate, planStartDate, numPmts, dayBetweenPmts);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }
        public static double calculateAmountOwed(int invoiceId)
        {
            double ret_value = 0;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isCalculateAmountOwed(_ApiKey, invoiceId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = -1;
            }

            return ret_value;
        }

        /// <summary>
        /// getAllPaymentOptions is used to retrieve all Payment Types currently setup under the Order Settings section of Infusionsoft
        /// </summary>
        /// <returns>(struct) all valid payment types currently setup in the application. Returns a single structure containing key called ErrorMessage with the value containing the message of the error.</returns>
        public static XmlRpcStruct[] getAllPaymentOptions()
        {
            XmlRpcStruct[] ret_value;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isGetAllPaymentOptions(_ApiKey);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = new XmlRpcStruct[1] { fail };
            }
            return ret_value;
        }
        // Returns all valid payment types as set up in the CRM
        // Array
        // (
        //     [Credit Card] => Credit Card
        //     [Check] => Check
        //     [Cash] => Cash
        //     [Money Order] => Money Order
        //     [Adjustment] => Adjustment
        //     [Credit] => Credit
        //     [Refund] => Refund
        // )

        // public static array getPayments()

        /// <summary>
        /// locateExistingCard finds a credit card on file for a contactId that matches the last four digits of the card. Make sure to send only the last four digits of the credit card.
        /// </summary>
        /// <param name="contactId"></param>
        /// <param name="last4"></param>
        /// <returns>(int) creditCardId if the card is found. Zero if no card matches</returns>
        public static int locateExistingCard(int contactId, string last4)
        {
            int cardId = 0;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                cardId = api.isLocateExistingCard(_ApiKey, contactId, last4);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                cardId = 0;
            }

            return cardId;
        }

        public static bool recalculateTax(int invoiceId)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isRecalculateTax(_ApiKey, invoiceId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }
        public static XmlRpcStruct validateCreditCard(int creditCardId)
        {
            XmlRpcStruct paymentDetails = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                paymentDetails = api.isValidateCreditCard(_ApiKey, creditCardId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                //paymentDetails = ;
            }

            return paymentDetails;
        }
        #endregion

        #region Misc methods
        /// <summary>
        /// getAllShippingOptions() creates a string array of all the available shipping options for this InfusionSoft Application
        /// </summary>
        /// <returns>Returns a string array of all the available shipping</returns>
        public static string[] iGetAllShippingOptions()
        {
            string[] AllShippingOptions = { };

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                AllShippingOptions = api.isGetAllShippingOptions(_ApiKey);
            }
            catch (Exception ex)
            {
                _LastException = ex;
            }

            return AllShippingOptions;
        }

        /// <summary>
        /// getPluginStatus retrieves the current status of the given plugin
        /// </summary>
        /// <param name="fullyQualifiedClassName"></param>
        /// <returns>(string) the current status of the plugin</returns>
        //public static String getPluginStatus(string fullyQualifiedClassName)
        //{
        //    String ret_value = string.Empty;
        //    _LastException = null;
        //    try
        //    {
        //        InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
        //        api.Url = _ApiURL;
        //        ret_value = api.isGetPluginStatus(_ApiKey, fullyQualifiedClassName);
        //    }
        //    catch (Exception ex)
        //    {
        //        _LastException = ex;
        //        ret_value = string.Empty;
        //    }
        //    return ret_value;
        //}

        public static bool addOrderCommissionOverride(int invoiceId, int affiliateId, int productId, int percentage, double amount, int payoutType, string description, string date)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isAddOrderCommissionOverride(_ApiKey, invoiceId, affiliateId, productId, percentage, amount, payoutType, description, date);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }
        public static bool deactivateCreditCard(int creditCardId)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.isDeactivateCreditCard(_ApiKey, creditCardId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }

        
        #endregion

        #endregion

         #region ProductService
        public static int getInventory(int productId)
        {
            int newOrderNumber = 0;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                newOrderNumber = api.psGetInventory(_ApiKey, productId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                newOrderNumber = -1;
            }

            return newOrderNumber;
        }
        public static bool incrementInventory(int productId)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.psIncrementInventory(_ApiKey, productId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }
        public static bool decrementInventory(int productId)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.psDecrementInventory(_ApiKey, productId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }
        public static bool increaseInventory(int productId, int quantity)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.psIncreaseInventory(_ApiKey, productId, quantity);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }
        public static bool decreaseInventory(int productId, int quantity)
        {
            bool ret_value = false;

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.psDecreaseInventory(_ApiKey, productId, quantity);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = false;
            }

            return ret_value;
        }
        //public static Boolean deactivateCreditCard(int creditCardId)
        //{
        //    Boolean ret_value = false;

        //    _LastException = null;
        //    try
        //    {
        //        InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
        //        api.Url = _ApiURL;
        //        ret_value = api.psDeactivateCreditCard(_ApiKey, creditCardId);
        //    }
        //    catch (Exception ex)
        //    {
        //        _LastException = ex;
        //        ret_value = false;
        //    }

        //    return ret_value;
        //}
        #endregion

        #region SearchService
        public static XmlRpcStruct getAllReportColumns(int savedSearchId, int userId)
        {
            XmlRpcStruct paymentDetails = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                paymentDetails = api.ssGetAllReportColumns(_ApiKey, savedSearchId, userId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                //paymentDetails = ;
            }

            return paymentDetails;
        }
        public static XmlRpcStruct getSavedSearchResultsAllFields(int savedSearchId, int userId, int pageNumber)
        {
            XmlRpcStruct paymentDetails = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                paymentDetails = api.ssGetSavedSearchResultsAllFields(_ApiKey, savedSearchId, userId, pageNumber);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                //paymentDetails = ;
            }

            return paymentDetails;
        }
        public static XmlRpcStruct getAvailableQuickSearches(int userId)
        {
            XmlRpcStruct paymentDetails = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                paymentDetails = api.ssGetAvailableQuickSearches(_ApiKey, userId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                //paymentDetails = ;
            }

            return paymentDetails;
        }
        public static XmlRpcStruct quickSearch(int quickSearchType, int userId, int searchData, int page, int returnLimit)
        {
            XmlRpcStruct paymentDetails = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                paymentDetails = api.ssQuickSearch(_ApiKey, quickSearchType, userId, searchData, page, returnLimit);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                //paymentDetails = ;
            }

            return paymentDetails;
        }
        public static string getDefaultQuickSearch(int userId)
        {
            string ret_value = string.Empty;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.ssGetDefaultQuickSearch(_ApiKey, userId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                ret_value = string.Empty;
            }
            return ret_value;
        }
        #endregion

        #region ShippingService
        public static XmlRpcStruct[] getAllShippingOptions()
        {
            XmlRpcStruct[] retStructArray;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                retStructArray = api.shsGetAllShippingOptions(_ApiKey);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                XmlRpcStruct[] retFail = new XmlRpcStruct[1] { fail };
                retStructArray = retFail;
            }
            return retStructArray;
        }
        public static XmlRpcStruct getFlatRateShippingOption(int optionId)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.shsGetFlatRateShippingOption(_ApiKey, optionId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }

            return ret_value;
        }
        public static XmlRpcStruct[] getOrderTotalShippingOption(int optionId)
        {
            XmlRpcStruct[] retStructArray;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                retStructArray = api.shsGetOrderTotalShippingOption(_ApiKey, optionId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                XmlRpcStruct[] retFail = new XmlRpcStruct[1] { fail };
                retStructArray = retFail;
            }
            return retStructArray;
        }
        public static XmlRpcStruct[] getOrderTotalShippingRanges(int optionId)
        {
            XmlRpcStruct[] retStructArray;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                retStructArray = api.shsGetOrderTotalShippingRanges(_ApiKey, optionId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                XmlRpcStruct[] retFail = new XmlRpcStruct[1] { fail };
                retStructArray = retFail;
            }
            return retStructArray;
        }
        public static XmlRpcStruct getProductBasedShippingOption(int optionId)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.shsGetProductBasedShippingOption(_ApiKey, optionId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }

            return ret_value;
        }
        public static XmlRpcStruct getProductShippingPricesForProductShippingOption(int optionId)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.shsGetProductShippingPricesForProductShippingOption(_ApiKey, optionId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }

            return ret_value;
        }
        public static XmlRpcStruct getOrderQuantityShippingOption(int optionId)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.shsGetOrderQuantityShippingOption(_ApiKey, optionId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }

            return ret_value;
        }
        public static XmlRpcStruct getWeightBasedShippingOption(int optionId)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.shsGetWeightBasedShippingOption(_ApiKey, optionId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }

            return ret_value;
        }
        public static XmlRpcStruct getWeightBasedShippingRanges(int optionId)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.shsGetWeightBasedShippingRanges(_ApiKey, optionId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }

            return ret_value;
        }
        public static XmlRpcStruct getUpsShippingOption(int optionId)
        {
            XmlRpcStruct ret_value = new XmlRpcStruct();

            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.shsGetUpsShippingOption(_ApiKey, optionId);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = fail;
            }

            return ret_value;
        }
        #endregion

        #region WebFormService
        public static XmlRpcStruct[] getMap()
        {
            XmlRpcStruct[] ret_value;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                ret_value = api.wfsGetMap(_ApiKey);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                XmlRpcStruct fail = new XmlRpcStruct();
                fail.Add("ErrorMessage", ex.Message);
                ret_value = new XmlRpcStruct[1] { fail };
            }
            return ret_value;
        }
        #endregion

        #region Utilities
        /// <summary>
        /// appEcho will return the string that you pass to it back from the InfusionSoft server. Good for testing your connectivity to the server.
        /// </summary>
        /// <param name="textToEcho">String to be echoed back to you</param>
        /// <returns>A string that is identical to the string you passed to this method.</returns>
        public static string appEcho(string textToEcho)
        {
            string return_value = null;
            _LastException = null;
            try
            {
                InfusionSoftApiInterfaces api = XmlRpcProxyGen.Create<InfusionSoftApiInterfaces>();
                api.Url = _ApiURL;
                return_value = api.appEcho(textToEcho);
            }
            catch (Exception ex)
            {
                _LastException = ex;
                return_value = String.Format("Error: Unable to echo server.<br />{0}<br />",
                    ex.Message);
            }

            return return_value;
        }

        #endregion

    }
}
